﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Docentric.Word;
using IBS.Model;
using IBS.ServiceContracts;

namespace IBS.Bll.Bills
{
    public class BillService : ServiceBase, IBillService
    {
        #region Private

        private const string TEMPLATE_PATH = "bill_template.docx";
        private static string pathToBills = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/Bills");
        
        #endregion

        #region Constructors

        public BillService(IIbsContext context) : base(context)
        {
        }

        #endregion

        public Bill GenerateBill(Transfer transfer)
        {
            Bill resultBill = new Bill();
            resultBill.BillNumber = transfer.Id;
            resultBill.BankName = "IBS";
            resultBill.Date = transfer.StartDate;
            resultBill.ISO = transfer.operationISO;
            resultBill.FromAccountNumber = transfer.FromAccount.Number;
            resultBill.ToAccountNumber = transfer.ToAccount.Number;
            switch ((TransferType) transfer.TransferType)
            {
                case TransferType.ToCard:
                    resultBill.OperationName = "Card Transfer";
                    break;
                case TransferType.ToAccount:
                    resultBill.OperationName = "Account Transfer";
                    break;
                case TransferType.ToPayment:
                    resultBill.OperationName = "Payment";
                    break;
                case TransferType.ToAutoPayment:
                    resultBill.OperationName = "AutoPayment";
                    break;
                case TransferType.Deposit:
                    resultBill.OperationName = "Deposit";
                    break;
                case TransferType.Withdraw:
                    resultBill.OperationName = "Withdraw";
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            resultBill.Amount = (TransferType) transfer.TransferType == TransferType.Deposit
                                    ? transfer.ToAccountAmount
                                    : transfer.FromAccountAmount;
            return resultBill;
        }

        public string GetBill(Bill bill, string outputFileName = null)
        {

            string reportDocumentFileName = outputFileName ?? bill.BillNumber.ToString() + ".docx";
            reportDocumentFileName = GetFullName(reportDocumentFileName);
            
            using (Stream reportDocumentStream = new FileStream(reportDocumentFileName, FileMode.Create))
            {
                // Open the report template file.
                using (Stream reportTemplateStream = GetReportTemplate())
                {
                    // Generate the report document using 'DocumentGenerator'.
                    DocumentGenerator dg = new DocumentGenerator(bill);
                    DocumentGenerationResult result = dg.GenerateDocument(reportTemplateStream, reportDocumentStream);
                    if (result.HasErrors)
                    {
                        foreach (Docentric.Word.Error error in result.Errors)
                            Console.Out.WriteLine(error.Message);
                    }
                    reportDocumentStream.Flush();
                }
            }
            return reportDocumentFileName;
        }

        private static string GetFullName(string fileName)
        {
            return Path.Combine(pathToBills, fileName);
        }

    private static Stream GetReportTemplate()
        {

            return File.Open(GetFullName(TEMPLATE_PATH), FileMode.Open);
        }
    }
}
